// /**
//  * qiankun配置
//  */
import * as qiankun from 'qiankun';
import type { RegistrableApp } from 'qiankun';
import { getToken } from '/@/utils/auth';
import { useMultipleTabStore } from '/@/store/modules/multipleTab';
import { RouteLocationNormalized } from 'vue-router';
import { reactive } from 'vue';
import { router } from '/@/router';
import { useTabs } from '/@/hooks/web/useTabs';

export type ProjectMicroapp = {
  entry: string;
  /** 微应用名称 */
  name: string;
  /** 微应用 base，由容器运行时确定 */
  base?: string;
  /** 激活微应用的 URL 前缀 */
  pathname: string;
  /** 沙箱启动状态 */
  sandbox?: boolean;
};

const join = (...paths: string[]) => {
  return paths.join('/').replace(/\/{1,}/g, '/');
};

export default class MicroappService {
  public registrableMicroapps: Array<RegistrableApp<any>> = [];
  actions: qiankun.MicroAppStateActions | null = null;
  propsData = reactive({
    themeColor: '',
    themeMode: '',
    local: '',
  });
  init(container, microapps: ProjectMicroapp[]) {
    this.registrableMicroapps = this.initMicroapps(container, microapps);
    this.start();
  }

  initMicroapps(container, microapps: ProjectMicroapp[]) {
    const registrMicroapps = microapps.map((microapp: ProjectMicroapp) => {
      const { name, pathname, entry, base = '', sandbox } = microapp;
      return {
        name,
        entry,
        container,
        sandbox,
        activeRule: join('/', pathname),
        props: {
          name,
          basename: join('/', base, pathname),
          token: getToken(),
          utils: {},
          propsData: this.propsData,
          tabs: this.proxyTabs(),
        },
      };
    });
    return registrMicroapps;
  }
  handleRoute(data: Record<string, any>) {
    const route: any = {
      ...(data || {}),
      path: data.path,
      fullPath: data.href || data.fullPath,
    };
    route.meta = {
      ...(data.meta || {}),
    };
    if (data.title) {
      route.meta.title = data.title;
    }
    return route;
  }
  proxyTabs() {
    return {
      addTab: (route: RouteLocationNormalized) => {
        const formatRoute = this.handleRoute(route);
        useMultipleTabStore().addTab(formatRoute as RouteLocationNormalized);
        router.push(formatRoute.fullPath || formatRoute.path);
      },
      refreshPage: () => {
        return useMultipleTabStore().refreshPage(router);
      },
      closeTab: (route: RouteLocationNormalized) => {
        const path = route?.fullPath ?? router.currentRoute.value?.fullPath;
        return useMultipleTabStore().closeTabByKey(path, router);
      },
      closeTabByKey: (path: string) => {
        return useMultipleTabStore().closeTabByKey(path, router);
      },
      closeLeftTabs: (route: RouteLocationNormalized) => {
        return useMultipleTabStore().closeLeftTabs(route, router);
      },
      closeRightTabs: (route: RouteLocationNormalized) => {
        return useMultipleTabStore().closeRightTabs(route, router);
      },
      closeAllTab: () => {
        return useMultipleTabStore().closeAllTab(router);
      },
      closeOtherTabs: (route: RouteLocationNormalized) => {
        return useMultipleTabStore().closeOtherTabs(route, router);
      },
    };
  }

  setGlState(data) {
    Object.assign(this.propsData, data || {});
    this.actions?.setGlobalState({
      ...this.propsData,
      ...(data || {}),
    });
    console.log(this.propsData);
  }

  initGlState() {
    const actions = qiankun.initGlobalState(this.propsData);
    this.actions = actions;
    this.actions.onGlobalStateChange((newState, prev) => {
      console.info('newState', newState);
      console.info('prev', prev);
      for (const key in newState) {
        console.info('onGlobalStateChange', key);
      }
    });
  }

  destory() {}

  start() {
    qiankun.registerMicroApps(this.registrableMicroapps, {
      beforeLoad: [
        // @ts-ignore
        (loadApp) => {
          console.log('before load', loadApp);
        },
      ],
      beforeMount: [
        // @ts-ignore
        (mountApp) => {
          console.log('before mount', mountApp);
        },
      ],
      afterMount: [
        // @ts-ignore
        (mountApp) => {
          console.log('after mount', mountApp);
        },
      ],
      afterUnmount: [
        // @ts-ignore
        (unloadApp) => {
          console.log('after unmount', unloadApp);
        },
      ],
    });
    qiankun.addGlobalUncaughtErrorHandler((event) => console.log(event));
    this.initGlState();
    qiankun.start({});
  }
}

const microappService = new MicroappService();

export { microappService };
